import { Checkbox, DatePicker, Input, InputNumber, Select, Switch } from "antd";
import React, { useCallback, useEffect, useState } from 'react';
import { SelectOutlined } from '@ant-design/icons';
import FillTable from "./FillTable";
import UploadField from "./UploadField";

function EditableCell({ column, value, onChange }) {
  const [val, setVal] = useState(value);

  const onCellChange = useCallback((value) => {
    setVal(value);
    onChange(value);
  }, [onChange]);

  useEffect(() => {
    setVal(value);
  }, [value]);

  const editorType = typeof (column.editor) === 'string' ? column.editor : column.editor?.type;
  const editorProps = typeof (column.editor) === 'string' ? {} : column.editor?.props ?? {};
  switch (editorType) {
    case 'number': {
      return <InputNumber value={val} size="default" onChange={onCellChange}
        onClick={e => e.stopPropagation()} {...editorProps} />
    }
    case 'date': {
      return <DatePicker value={val} showTime={false} size="default" onChange={onCellChange}
        format="YYYY-MM-DD" {...editorProps} />
    }
    case 'time': {
      return <DatePicker value={val} showTime={true} size="default" onChange={onCellChange}
        format="YYYY-MM-DD HH:mm:ss" {...editorProps} />
    }
    case 'checkbox': {
      return <Checkbox defaultChecked={Boolean(val)} onChange={e => onCellChange(e.target.checked)}  {...editorProps} />
    }
    case 'switch': {
      return <Switch defaultChecked={Boolean(val)} onChange={checked => onCellChange(checked)} {...editorProps} />
    }
    case 'dropdown': {
      return <Select value={val} allowClear={true} size="default" style={{ width: '100%' }}
        onChange={onCellChange} options={column.options || []} {...editorProps} />
    }
    case 'popup': {
      return <Input value={val} size="default"
        suffix={<SelectOutlined onClick={() => column.onPopupSelect(onCellChange)} />}
        onClick={() => column.onPopupSelect(onCellChange)} {...editorProps} />
    }
    case 'file': {
      return <UploadField listType="text" onChange={onCellChange} {...editorProps} />
    }
    case 'text':
    default: {
      return <Input value={val} size="default" onChange={e => onCellChange(e.target.value)}
        onClick={e => e.stopPropagation()} {...editorProps} />
    }
  }
}

export default function EditableTable({ columns, dataSource, onValuesChange, ...props }) {
  const [local_columns, setLocalColumns] = useState([]);
  const [rows, setRows] = useState(dataSource);

  useEffect(() => {
    setLocalColumns(columns.filter((column) => !column.hidden).map((column) => ({
      ...column,
      render: (text, record, index) => {
        const editable = column.editable ?? (() => true);
        if (column.editor && editable(record)) {
          return <EditableCell column={column} value={text}
            onChange={value => {
              record[column.dataIndex] = value;
              if (onValuesChange) onValuesChange({ [column.dataIndex]: value }, record, index);
              setRows([...rows]);
            }} />
        } else {
          return column.render ? column.render(text, record, index) : text;
        }
      }
    })));
  }, [columns, rows, onValuesChange]);

  useEffect(() => {
    setRows(dataSource);
  }, [dataSource]);

  return <FillTable dataSource={rows} {...props} columns={local_columns} />;
}